package com.strato.i18n.v1_0_0.discover;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;

import com.strato.i18n.v1_0_0.Messages;

public class ResourceBundleDiscover implements BundleListener {

	private Map<String,Map<String,Properties>> resources=new HashMap<String,Map<String,Properties>>();
	
	public Map<String, Map<String, Properties>> getResources() {
		return resources;
	}

	public void setResources(Map<String, Map<String, Properties>> resources) {
		this.resources = resources;
	}

	public void onInstalled(Bundle bundle) {
		Map<String,Properties> map=resolveResourceBundle(bundle);
		if(map!=null){
			resources.put(bundle.getSymbolicName(), map);
		}
	}

	private Map<String,Properties> resolveResourceBundle(Bundle bundle) {
		URL entry = bundle.getEntry("META-INF/i18n");
		if(entry==null){
			return null;
		}
		String defaultLocale=Messages.DEFAULT_LOCALE;
		Map<String,Properties> map=new HashMap<String,Properties>();
		URL url=getResource(bundle,defaultLocale);
		if(url!=null){
			Properties p=loadProperties(url);
			map.put(defaultLocale, p);
		}
		for(Locale locale:Locale.getAvailableLocales()){
			String localeName=locale.toLanguageTag();
			URL u = getResource(bundle,localeName);
			if(u!=null){
				Properties p=loadProperties(u);
				if(p!=null&&!p.isEmpty()){
					map.put(localeName, p);
				}
			}
		}
		return map;
	}

	private Properties loadProperties(URL url) {
		Reader r=null;
		try {
			r=new InputStreamReader(url.openStream(),Charset.forName("UTF-8"));
			Properties p=new Properties();
			p.load(r);
			return p;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}finally{
			if(r!=null){
				try {
					r.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private URL getResource(Bundle bundle,String locale) {
		if(!"".equals(locale)){
			locale="_"+locale;
		}
		return bundle.getResource("META-INF/i18n/messages"+locale+".properties");
	}

	public void onUninstalled(Bundle bundle) {
		resources.remove(bundle.getSymbolicName());
	}

	@Override
	public void bundleChanged(BundleEvent event) {
		if(event.getType()==BundleEvent.INSTALLED){
			onInstalled(event.getBundle());
		}else if(event.getType()==Bundle.UNINSTALLED){
			onUninstalled(event.getBundle());
		}
	}

	public Set<String> getLocales(){
		Set<String> set=new HashSet<String>();
		Collection<Map<String, Properties>> maps = resources.values();
		for(Map<String, Properties> map:maps){
			set.addAll(map.keySet());
		}
		return set;
	}
}
